import * as THREE from 'three'
import { MySprite } from './MySprite'
import { ClickHandler } from '../utils/ClickHandler'
import gsap from 'gsap'
import { EventBus } from '../utils/EventBus'
// 定义汽车类
export class Car {
  constructor(model, scene, camera, controls) {
    this.model = model
    this.scene = scene
    this.camera = camera
    this.controls = controls

    // 车的小模型对象
    this.carModel = {
      body: { //车身
        main: {
          name: 'Object_103',
          model: {}
        },
        roof: { //顶部
          name: 'Object_110',
          model: {}
        },
        leftDoor: { //左车门
          name: 'Object_64',
          model: {},
          mark: [
            {
              name: 'sprite',
              url: 'image/sprite.png',
              position: [1.07, 1.94, -0.23],
              scale: [0.2, 0.2]
            }
          ]
        },
        rightDoor: { // 右车门
          name: 'Object_77',
          model: {},
          mark: [
            {
              name: 'sprite',
              url: 'image/sprite.png',
              position: [-1.05, 0.78, -0.23],
              scale: [0.2, 0.2]
            }
          ]
        }
      },
      glass: { // 玻璃
        'front': { // 前玻璃
          name: 'Object_90',
          model: {}
        },
        'leftGlass': { // 左玻璃
          name: 'Object_68',
          model: {}
        },
        'rightGlass': { // 右玻璃
          name: 'Object_81',
          model: {}
        }
      }
    }

    // 车数值相关（记录用于发给后台-保存用户要购车相关信息）
    this.info = {
      allPrice: 2444700, // 车整体默认总价
      color: [
        {
          name: '土豪金',
          color: '#ff9900',
          isSelected: true
        },
        {
          name: '传奇黑',
          color: '#343a40',
          isSelected: false
        },
        {
          name: '海蓝',
          color: '#409EFF',
          isSelected: false
        },
        {
          name: '玫瑰紫',
          color: '#6600ff',
          isSelected: false
        },
        {
          name: '银灰色',
          color: '#DCDFE6',
          isSelected: false
        }
      ],
      // 贴膜
      film: [
        {
          name: '高光',
          price: 0,
          isSelected: true
        },
        {
          name: '磨砂',
          price: 20000,
          isSelected: false
        }
      ]
    }

    // 汽车各种视角坐标对象
    this.positionObj = {
      // 主驾驶
      main: {
        camera: {
          x: 0.36,
          y: 0.96,
          z: -0.16
        },
        controls: {
          x: 0.36,
          y: 0.87,
          z: 0.03
        }
      },
      // 副驾驶位
      copilot: {
        camera: {
          x: -0.39,
          y: 0.87,
          z: 0.07
        },
        controls: {
          x: -0.39,
          y: 0.85,
          z: 0.13
        }
      },
      // 外面观察
      outside: {
        camera: {
          x: 3,
          y: 1.5,
          z: 3
        },
        controls: {
          x: 0,
          y: 0,
          z: 0
        }
      }
    }

    // 调用初始化方法
    this.init()
    // 改变车身颜色
    this.modifyCarStyle()
    // 车门精灵图
    this.createDoorSprite()
  }
  // 初始化汽车
  init() {
    this.scene.add(this.model)
    this.model.traverse(obj => obj.castShadow = true)
    // 通过数据结构名字 将小物体的对象保存在carModel中 getObjectByName是Three.js提供的方法 不是原生js方法
    Object.values(this.carModel.body).forEach(obj => {
      obj.model = this.model.getObjectByName(obj.name)
    })
    // 玻璃相关
    Object.values(this.carModel.glass).forEach(obj => {
      obj.model = this.model.getObjectByName(obj.name)
    })
    // 订阅汽车修改颜色的事件和函数体
    EventBus.getInstance().on('changeCarColor', (colorStr) => {
      Object.values(this.carModel.body).forEach(obj => {
        obj.model.material.color = new THREE.Color(colorStr)
      })
      // 保存用户所选的车的颜色
      this.info.color.forEach(obj => {
        obj.isSelected = false
        if (obj.color === colorStr) {
          obj.isSelected = true
        }
      })
    })
    // 订阅汽车贴膜修改的事件和函数体
    EventBus.getInstance().on('changeCarCoat', (coatName) => {
      Object.values(this.carModel.body).forEach(obj => {
        if (coatName === '高光') {
          obj.model.material.roughness = 0.5
          obj.model.material.metalness = 1
          obj.model.material.claercoat = 1
        } else if (coatName === '磨砂') {
          obj.model.material.roughness = 1 //粗糙度
          obj.model.material.metalness = 0 //金属度
          obj.model.material.claercoat = 0 //薄膜
        }
      })

      // 保存用户选择的贴膜类型

      this.info.film.forEach(obj => {

        obj.isSelected = false
        if (obj.name === coatName) {
          obj.isSelected = true
        }
      })
    })
    // 订阅计算总价的事件
    EventBus.getInstance().on('countAllPrice', () => {
      const filmTarget = this.info.film.find(filmObj => {
        return filmObj.isSelected === true
      })
      const price = this.info.allPrice + filmTarget.price
      document.querySelector('.price>span').innerHTML = `¥ ${price.toFixed(2)}`
    })
    // 订阅汽车视角切换的事件
    EventBus.getInstance().on('changeCarAngleView', (viewName) => {
      this.setCameraAnimation(this.positionObj[viewName])
    })
  }
  modifyCarStyle() {
    const bodyMaterial = new THREE.MeshPhysicalMaterial({
      color: 0xff9900,
      roughness: 0.5,
      metalness: 1,
      clearcoat: 1,
      clearcoatRoughness: 0
    })
    Object.values(this.carModel.body).forEach(obj => {
      obj.model.material = bodyMaterial
    })
    // 改变玻璃的渲染面
    Object.values(this.carModel.glass).forEach(obj => {
      obj.model.material.side = THREE.FrontSide
    })
    // 车顶双面渲染
    this.carModel.body.roof.model.material.side = THREE.DoubleSide
  }
  // 创建车门上的精灵图
  createDoorSprite() {
    const markList = [this.carModel.body.leftDoor, this.carModel.body.rightDoor]
    markList.forEach(obj => {
      obj.mark.forEach(mark => {
        if (mark.name === 'sprite') {
          // 创建一个新的精灵物体
          const sprite = new MySprite(mark)
          // 对应的model上面添加精灵图
          obj.model.add(sprite)
          ClickHandler.getInstance().addMesh(sprite, (clickThreeObj) => {
            // clickThreeObj 精灵物体
            // clickThreeMesh.parent Object_77 车门物体 坐标轴原点在世界坐标系中心 旋转车门有问题
            // clickThreeMesh.parent.parent.parent  车门的最大物体对象
            const targetDoor = clickThreeObj.parent.parent.parent // 精灵图的父级物体对象 车门
            //  判断车门是否是开启状态
            if (!targetDoor.userData.isOpen) {
              // 没开门
              this.setDoorAnimation(targetDoor, { x: Math.PI / 4 })
              targetDoor.userData.isOpen = true
            } else {
              // 关门
              this.setDoorAnimation(targetDoor, { x: 0 })
              targetDoor.userData.isOpen = false
            }
          })
        }
      })
    })
  }
  // 做一个开门的动画
  setDoorAnimation(mesh, animationObj) {
    gsap.to(mesh.rotation, {
      x: animationObj.x,
      duration: 2,
      ease: "power1.inOut"
    })
  }
  // 做一个视角切换的动画 摄像机 轨道控制器的动画
  setCameraAnimation(dataObj) {
    gsap.to(this.camera.position, {
      ...dataObj.camera,
      duration: 1,
      ease: 'power1.in'
    })
    gsap.to(this.controls.target, {
      ...dataObj.controls,
      duration: 1,
      ease: 'power1.in'
    })
  }
}
